﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Data.Entity;
using System.Data.Objects;
using System.Text;
using System.Threading.Tasks;
using Trauberman.SOChat.StarLeaderboard.Data;
using Trauberman.SOChat.StarLeaderboard.Domain;
using System.Data.SqlClient;
using System.Data.Entity.Infrastructure;

namespace Trauberman.SOChat.StarLeaderboard.Services
{
    public class StarService : IStarService
    {
		private IDataContext _data;
		public StarService(IDataContext data)
		{
			_data = data;
		}

		public IQueryable<StarredMessage> GetStarsByRoom(int chatRoomId)
		{
			return _data.Stars.Where(s => s.ChatRoom == chatRoomId).Include(s => s.User);
		}

        public IQueryable<StarredMessage> GetStarsByUser(int userId)
        {
            return _data.Stars.Where(s => s.User.SOid == userId).Include(s=>s.User);
        }

		public void InsertOrUpdate(IList<StarredMessage> messages)
		{
			var knownStarredMessages = _data.Stars.Select(s => new { s.SOid, s.StarCount }).ToList();

			// if the StarredMessage exists, update the count, otherwise insert the new star
			foreach (StarredMessage msg in messages)
			{
				if (!knownStarredMessages.Any(s => s.SOid == msg.SOid))
				{					
					Console.WriteLine("    Inserting message {0} ({1}/{2})", msg.SOid, messages.IndexOf(msg), messages.Count());
					_data.Stars.Add(msg);
					knownStarredMessages.Add(new { msg.SOid, msg.StarCount });
				}
				else if (knownStarredMessages.Single(s => s.SOid == msg.SOid).StarCount != msg.StarCount)
					{
					Console.WriteLine("    Updating message {0} ({1}/{2})", msg.SOid, messages.IndexOf(msg), messages.Count());
					(_data as IObjectContextAdapter).ObjectContext.ExecuteStoreCommand(
						"UPDATE StarredMessages SET StarCount = @starcount WHERE SOid = @id",
						new SqlParameter() { ParameterName = "starcount", Value = msg.StarCount },
						new SqlParameter() { ParameterName = "id", Value = msg.SOid }
						);
				}
			}

			_data.SaveChanges();
		}
	}
}
